﻿#include "../../beans/headers/FlowLineItem.h"

FlowLineItem::FlowLineItem(QGraphicsItem *parent):
    QGraphicsLineItem(parent)
{
    // 设置自定义的Item可以被选中和移动
    this->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);

    //  使其在端口DotItem图层下面
    this->setZValue(-2);

    this->setData(ITEM_CLASS,EnumType::ItemClass_FLowLineItem);
}

// 所有绘制都要被限制在这个矩形内部
QRectF FlowLineItem::boundingRect(void) const
{
    // 返回默认的boundingRect（是加粗后的矩形，包括了碰撞区域和显示区域的并集矩形区域）
    return QGraphicsLineItem::boundingRect();
}

void FlowLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{

    QStyleOptionGraphicsItem optionOne;
    optionOne.initFrom(widget);

    // 如果选中的线被取消选中则将状态恢复
    if(option->state & QStyle::State_Selected)
    {
        optionOne.state = QStyle::State_None;
    }

    // 如果线被选中
    if(option->state & QStyle::State_Selected)
    {
        painter->setBrush(Qt::NoBrush);
        painter->setPen(QPen(QColor(Qt::red),2,Qt::DashLine));

        // 如果线没有被选中
    }else
    {
        painter->setPen(QPen(QColor(Qt::black),1));
    }

    painter->drawLine(this->line());

    // 查看path效果
    // painter->drawPath(this->shape());
}

// 碰撞检测的轮廓（被contains() 和 collidesWithPath()使用）
QPainterPath FlowLineItem::shape(void) const
{
    // 这个判定区域的宽度(在线的周围外扩(width/2)的宽度)
    qreal width = 10 ;
    QPainterPath path;
    QPainterPathStroker stroker;

    path = QGraphicsLineItem::shape();
    stroker.setWidth(width);
    path = stroker.createStroke(path);

    return path;
}

// 辅助函数（碰撞检测两个父级别Item是否碰撞）
bool FlowLineItem::collidingItems(void)
{
    // 获取所有碰撞检测到的QGraphicsItem（包括自己的子Item）
    QList<QGraphicsItem *> QGraphicsItemList = this->scene()->collidingItems(this);
    QGraphicsItem *tempItem;

    // 获取BlockItem的每一个子Item
    foreach(tempItem, QGraphicsItemList)
    {
        // 如果子Item的父BlockItem不是此BlockItem，且为空(不加为空判断会问题)
        if(tempItem->parentItem() != this && tempItem->parentItem() == Q_NULLPTR)
        {
            return true;
        }
    }

    return false;
}

// 外部函数（判断两条线是否重合）
bool FlowLineItem::isSuperposition(FlowLineItem *lineItem)
{
    qreal this_P1_x1 = this->line().p1().rx();
    qreal this_P1_y1 = this->line().p1().ry();
    qreal this_P2_x2 = this->line().p2().rx();
    qreal this_P2_y2 = this->line().p2().ry();

    qreal lineItem_P1_x1 = lineItem->line().p1().rx();
    qreal lineItem_P1_y1 = lineItem->line().p1().ry();
    qreal lineItem_P2_x2 = lineItem->line().p2().rx();
    qreal lineItem_P2_y2 = lineItem->line().p2().ry();

    // 如果两条线的两个点（也就是4个点）x轴都相等或者y轴都相等，那么这两条线就重合(没有考虑到点线)
    bool judgeFlag = (this_P1_x1 == this_P2_x2 && lineItem_P1_x1 == this_P1_x1 && lineItem_P1_x1 == lineItem_P2_x2)||
                     (this_P1_y1 == this_P2_y2 && lineItem_P1_y1 == this_P1_y1 && lineItem_P1_y1 == lineItem_P2_y2);
    // 去掉点线的情况
    bool isSuperposition = (this->line().p1() == this->line().p2() || lineItem->line().p1() == lineItem->line().p2() ? false : judgeFlag);
    return isSuperposition;
}

// 外部函数（判断线时水平还是竖直：true为竖直，false为水平）
bool FlowLineItem::isVH()
{
    return (this->line().p1().rx() == this->line().p2().rx() ? true : false);
}

// 外部函数（获取线的方向，只适用于正交线）
int FlowLineItem::lineDirection()
{
    QPointF vec = this->line().p2() - this->line().p1();

    if(vec.ry() > 0)
    {
        return EnumType::LineItem_Down;
    }
    else if(vec.ry() < 0)
    {
        return EnumType::LineItem_Up;
    }
    else if(vec.rx() > 0)
    {
        return EnumType::LineItem_Right;
    }
    else if(vec.rx() < 0)
    {
        return EnumType::LineItem_Left;
    }else
    {
        return EnumType::LineItem_Left;
    }
}

// 判断其是否是点线（首尾点重合的线）
bool FlowLineItem::isPointLine(void)
{
    return this->line().p1() == this->line().p2();
}

